import { useEffect, useState, useRef } from 'react';
import { Button } from 'antd';
import styles from './index.less';
// ../../assets

const CanvasDemo = (props) => {
  const [imgsList, setImgsList] = useState([]);
  const [renderList, setRenderList] = useState([]);
  const [scaleTime, setScaleTime] = useState(0.1); // 百分比
  const [cWidth, setCWidth] = useState();
  const [cHeight, setCHeight] = useState();
  const [context, setContext] = useState();
  const [scanning, setScanning] = useState(false);

  const timeRef = useRef();
  const animatRef = useRef();
  const renderListRef = useRef([]);
  const animatInterRef = useRef();

  useEffect(() => {
    loadImages();
    const canvas = document.getElementById('thumsCanvas');
    const context = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;

    setCWidth(width);
    setCHeight(height);
    setContext(context);

    return () => {
      clearInterval(timeRef.current);
    };
  }, []);
  // css start
  const initInterval = () => {
    let timer = setInterval(() => {
      addPraise();
    }, 300);
    timeRef.current = timer;
  };
  // Math.random()返回0-1之间随机数
  const addPraise = () => {
    const b = Math.floor(Math.random() * 6) + 1;
    const bl = Math.floor(Math.random() * 11) + 1; // bl1~bl11

    let d = document.createElement('div');
    let b_n = `b${b}`;
    let bl_n = `bl${bl}`;
    d.className = `${styles.bubble} ${styles[b_n]} ${styles[bl_n]}`;
    d.dataset.t = String(Date.now());
    let praiseBubble = document.getElementById('praise_bubble');
    praiseBubble.appendChild(d);
  };
  const endInterval = () => {
    clearInterval(timeRef.current);
  };
  // css end
  // --------
  // canvas start
  const getRandom = (min, max) => {
    return min + Math.floor(Math.random() * (max - min + 1));
  };
  const loadImages = () => {
    const images = [
      'jfs/t1/93992/8/9049/4680/5e0aea04Ec9dd2be8/608efd890fd61486.png',
      'jfs/t1/108305/14/2849/4908/5e0aea04Efb54912c/bfa59f27e654e29c.png',
      'jfs/t1/98805/29/8975/5106/5e0aea05Ed970e2b4/98803f8ad07147b9.png',
      'jfs/t1/94291/26/9105/4344/5e0aea05Ed64b9187/5165fdf5621d5bbf.png',
      'jfs/t1/102753/34/8504/5522/5e0aea05E0b9ef0b4/74a73178e31bd021.png',
      'jfs/t1/102954/26/9241/5069/5e0aea05E7dde8bda/720fcec8bc5be9d4.png',
    ];
    const promiseAll = [];
    images.forEach((src) => {
      const p = new Promise(function (resolve) {
        const img = new Image();
        img.onerror = img.onload = resolve.bind(null, img);
        img.src = 'https://img12.360buyimg.com/img/' + src;
      });
      promiseAll.push(p);
    });
    Promise.all(promiseAll).then((imgsList) => {
      const imgsList_n = imgsList.filter((d) => {
        if (d && d.width > 0) return true;
        return false;
      });
      if (imgsList_n.length == 0) {
        dLog('error', 'imgsList load all error');
        return;
      }
      setImgsList(imgsList_n);
    });
  };
  const createRender = () => {
    if (imgsList.length == 0) return null;
    const basicScale = [0.6, 0.9, 1.2][getRandom(0, 2)]; // 随机缩放比例

    const getScale = (diffTime) => {
      if (diffTime < scaleTime) {
        return +(diffTime / scaleTime).toFixed(2) * basicScale;
      } else {
        return basicScale;
      }
    };
    // 随机读取一个图片来渲染
    const image = imgsList[getRandom(0, imgsList.length - 1)];
    const offset = 20;
    const basicX = cWidth / 2 + getRandom(-offset, offset); // canvas中轴线附近[-20,20]范围
    const angle = getRandom(2, 10); // sin函数的紧凑程度
    let ratio = getRandom(10, 30) * (getRandom(0, 1) ? 1 : -1); // 随机[-30, -10][10 30]---（sin函数的幅度波动，决定动画左右摇摆幅度）
    const getTranslateX = (diffTime) => {
      // X 位移 sin函数得出
      if (diffTime < scaleTime) {
        // 放大期间，不进行摇摆位移
        return basicX;
      } else {
        return basicX + ratio * Math.sin(angle * (diffTime - scaleTime));
      }
    };

    const getTranslateY = (diffTime) => {
      return image.height / 2 + (cHeight - image.height / 2) * (1 - diffTime);
    };

    const fadeOutStage = getRandom(14, 18) / 100;
    const getAlpha = (diffTime) => {
      let left = 1 - +diffTime;
      if (left > fadeOutStage) {
        return 1;
      } else {
        return 1 - +((fadeOutStage - left) / fadeOutStage).toFixed(2);
      }
    };

    // 对canvas中特定元素的旋转平移等操作实际上是对整个画布进行了操作，所以如果不对canvas进行save以及restore，那么每一次绘图都会在上一次的基础上进行操作，最后导致错位。
    // diffTime = (Date.now() - child.timestamp) / child.duration (动画开始执行的时间间隔，0--> 1)
    return (diffTime) => {
      // 差值满了，即结束了 0 ---》 1
      if (diffTime >= 1) return true;
      // 记住Canvas状态
      context.save();
      const scale = getScale(diffTime);
      const translateX = getTranslateX(diffTime);
      const translateY = getTranslateY(diffTime);
      // Canvas画布的中心点为变换点进行旋转
      context.translate(translateX, translateY); // 位移的整个画布
      context.scale(scale, scale);
      context.globalAlpha = getAlpha(diffTime);
      context.drawImage(
        image,
        -image.width / 2,
        -image.height / 2,
        image.width,
        image.height,
      );
      // 恢复状态，不要影响接下来的绘制
      context.restore();
    };
  };
  // 不断的清除，绘制，每次绘制位置不同--动画轨迹的形成
  const scan = () => {
    context.clearRect(0, 0, cWidth, cHeight);
    context.fillStyle = '#f4f4f4';
    context.fillRect(0, 0, 200, 400);
    let index = 0;
    let length = renderListRef.current?.length;
    if (length > 0) {
      requestFrame(scan);
      setScanning(true);
    } else {
      setScanning(false);
    }
    while (index < length) {
      const child = renderListRef.current[index];
      if (
        !child ||
        !child.render ||
        child.render.call(null, (Date.now() - child.timestamp) / child.duration)
      ) {
        // 结束了，删除该动画
        renderListRef.current.splice(index, 1);
        length--;
      } else {
        // continue
        index++;
      }
    }
  };
  const start = () => {
    const render = createRender();
    const duration = getRandom(1500, 3000);
    renderListRef.current.push({
      render,
      duration,
      timestamp: Date.now(),
    });

    if (!scanning) {
      setScanning(true);
      requestFrame(scan);
    }
  };
  const end = () => {
    setScanning(false);
    clearInterval(animatInterRef.current);
  };
  const requestFrame = (cb) => {
    let ani_id = requestAnimationFrame(cb);
    animatRef.current = ani_id;
    // return (
    //   requestAnimationFrame ||
    //   window.webkitRequestAnimationFrame ||
    //   function(callback) {
    //     window.setTimeout(callback, 1000 / 60);
    //   }
    // )(cb);
    // return requestAnimationFrame(cb);
  };
  // 每次定时随机制作一个图片，频率越快，动画越密集
  const startAnimation = () => {
    const animatIntervalId = setInterval(() => {
      start();
    }, 300);
    animatInterRef.current = animatIntervalId;
    // start()
  };
  // canvas end
  return (
    <div className={styles.canvas_wrap}>
      <div className="container">
        <h2>CSS3:</h2>
        <div className={styles.praise_bubble} id="praise_bubble"></div>
        <Button type="primary" size="small" onClick={initInterval}>
          开始
        </Button>
        <Button type="primary" size="small" onClick={endInterval}>
          结束
        </Button>
      </div>
      <div className="container">
        <h2>Canvas:</h2>
        <canvas
          id="thumsCanvas"
          width="200"
          height="400"
          style={{ width: '100px', height: '200px' }}
        ></canvas>
        <Button type="primary" size="small" onClick={startAnimation}>
          开始
        </Button>
        <Button type="primary" size="small" onClick={end}>
          结束
        </Button>
      </div>
    </div>
  );
};

export default CanvasDemo;
